﻿// Decompiled with JetBrains decompiler
// Type: Microsoft.InfoCards.UIAgentRequest
// Assembly: infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// MVID: 8E14765A-6610-409A-BA36-099A0642905D
// Assembly location: E:\git\ALLIDA\windll\infocard.exe

using Microsoft.InfoCards.Diagnostics;
using Microsoft.Win32.SafeHandles;
using System;
using System.ComponentModel;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Principal;

namespace Microsoft.InfoCards
{
  internal abstract class UIAgentRequest : Request
  {
    private ClientUIRequest m_parentRequest;

    public UIAgentRequest(IntPtr rpcHandle, Stream inArgs, Stream outArgs, ClientUIRequest parent)
      : this(rpcHandle, inArgs, outArgs, parent, ExceptionList.Empty)
    {
    }

    public UIAgentRequest(
      IntPtr rpcHandle,
      Stream inArgs,
      Stream outArgs,
      ClientUIRequest parent,
      ExceptionList exceptionList)
      : base(rpcHandle, inArgs, outArgs, exceptionList)
    {
      this.m_parentRequest = parent;
    }

    public ClientUIRequest ParentRequest
    {
      get
      {
        return this.m_parentRequest;
      }
    }

    protected InfoCardUIAgent UIAgent
    {
      get
      {
        if (this.ParentRequest != null)
          return this.ParentRequest.UIAgent;
        return (InfoCardUIAgent) null;
      }
    }

    public static uint Authorize(IntPtr rpcIfHandle, IntPtr context)
    {
      uint num = 5;
      if (IntPtr.Zero == rpcIfHandle)
        throw InfoCardTrace.ThrowHelperArgumentNull(nameof (rpcIfHandle));
      if (IntPtr.Zero == context)
        throw InfoCardTrace.ThrowHelperArgumentNull(nameof (context));
      try
      {
        WindowsIdentity windowsIdentity = Utility.GetWindowsIdentity(context);
        try
        {
          InfoCardUIAgent byPid = InfoCardUIAgent.FindByPid(Utility.GetRpcClientPid(context));
          if (byPid == null)
            throw InfoCardTrace.ThrowHelperError((Exception) new SecurityException());
          NativeMcppMethods.CheckSIDAgainstCurrentRpcUser(byPid.TrustedUserSid);
          num = 0U;
        }
        finally
        {
          windowsIdentity.Dispose();
        }
      }
      catch (SecurityException ex)
      {
        InfoCardTrace.Assert(5U == num, "Unexpected value for err!");
      }
      catch (Exception ex)
      {
        InfoCardService.Crash(ex);
      }
      return num;
    }

    public static void BindToService(
      IntPtr uiagentRpcHandle,
      IntPtr nativeDesktopName,
      int cbUserSid,
      IntPtr pUserSid,
      int cbTrustedSid,
      IntPtr pTrustedSid,
      out IntPtr nativeStartEventHandle,
      out IntPtr nativeCompleteEventHandle,
      out RpcUIAgentGetWorkCallback callback)
    {
      string stringUni = Marshal.PtrToStringUni(nativeDesktopName);
      callback = (RpcUIAgentGetWorkCallback) null;
      nativeStartEventHandle = IntPtr.Zero;
      nativeCompleteEventHandle = IntPtr.Zero;
      using (WindowsIdentity windowsIdentity = Utility.GetWindowsIdentity(uiagentRpcHandle))
      {
        WindowsImpersonationContext impersonationContext = windowsIdentity.Impersonate();
        try
        {
          uint pid;
          if (NativeMethods.I_RpcBindingInqLocalClientPID(uiagentRpcHandle, out pid) != 0U)
            throw InfoCardTrace.ThrowHelperError((Exception) new CommunicationException(SR.GetString("FailedToBindToService")));
          InfoCardUIAgent byPid = InfoCardUIAgent.FindByPid(pid);
          if (byPid == null)
            return;
          SecurityIdentifier userSid;
          SafeWaitHandle hStartEvent;
          SafeWaitHandle hCompleteEvent;
          callback = byPid.Bind(stringUni, out userSid, out hStartEvent, out hCompleteEvent);
          byte[] numArray = new byte[Math.Max(cbUserSid, cbTrustedSid)];
          windowsIdentity.User.GetBinaryForm(numArray, 0);
          Marshal.Copy(numArray, 0, pUserSid, cbUserSid);
          userSid.GetBinaryForm(numArray, 0);
          Marshal.Copy(numArray, 0, pTrustedSid, cbTrustedSid);
          nativeStartEventHandle = hStartEvent.DangerousGetHandle();
          nativeCompleteEventHandle = hCompleteEvent.DangerousGetHandle();
        }
        finally
        {
          impersonationContext.Undo();
        }
      }
    }

    public override WindowsIdentity RequestorIdentity
    {
      get
      {
        return this.ParentRequest.RequestorIdentity;
      }
    }

    protected override void OnInitializeAsSystem()
    {
      try
      {
        NativeMcppMethods.CheckSIDAgainstCurrentRpcUser(this.ParentRequest.UIAgentLogonSid);
      }
      catch (Win32Exception ex)
      {
        throw InfoCardTrace.ThrowHelperError((Exception) new InfoCardArgumentException(SR.GetString("UnableToAuthenticateUIAgent"), (Exception) ex));
      }
      catch (SecurityException ex)
      {
        throw InfoCardTrace.ThrowHelperError((Exception) new InfoCardArgumentException(SR.GetString("UnableToAuthenticateUIAgent"), (Exception) ex));
      }
    }

    protected InfoCardPolicy GetPolicy()
    {
      return (this.ParentRequest as GetTokenRequest)?.Policy;
    }
  }
}
